package com.imut.lagain.controller;

import com.imut.lagain.common.Result;
import com.imut.lagain.entity.User;
import com.imut.lagain.entity.UserRole;
import com.imut.lagain.service.IUserService;
import com.imut.lagain.service.IUserRoleService;

import com.imut.lagain.service.NotificationService;
import com.imut.lagain.util.JwtUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import java.util.HashMap;
import java.util.Map;

/**
 * 手机号登录控制器
 */
@RestController
@RequestMapping("/phone-auth")
public class PhoneAuthController {
    private static final Logger log = LoggerFactory.getLogger(PhoneAuthController.class);

    private final IUserService userService;
    private final IUserRoleService userRoleService;
    private final NotificationService notificationService;
    private final JwtUtil jwtUtil;
    private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    @Autowired
    public PhoneAuthController(IUserService userService,
                               IUserRoleService userRoleService,
                               NotificationService notificationService,
                               JwtUtil jwtUtil) {
        this.userService = userService;
        this.userRoleService = userRoleService;
        this.notificationService = notificationService;
        this.jwtUtil = jwtUtil;
    }

    /**
     * 手机号密码登录
     */
    @PostMapping("/login")
    public Result<Map<String, Object>> login(@Valid @RequestBody PhoneLoginRequest request) {
        log.info("手机号登录请求: phone={}", request.getPhone());
        
        try {
            // 根据手机号查找用户
            User user = userService.getUserByPhone(request.getPhone());
            log.info("根据手机号查找用户结果: user={}", user);
            
            if (user == null) {
                log.warn("用户不存在: phone={}", request.getPhone());
                return Result.error("用户不存在");
            }
            
            // 获取用户角色信息
            UserRole userRole = userRoleService.getUserRole(user.getId());
            log.info("获取用户角色信息结果: userRole={}", userRole);
            
            if (userRole == null) {
                log.warn("用户角色不存在: userId={}", user.getId());
                return Result.error("用户角色配置错误");
            }
            
            // 验证密码 - 使用用户表中的密码字段
            log.info("验证密码: requestPassword={}, userPassword={}", request.getPassword(), user.getPassword());
            if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
                log.warn("密码错误: phone={}", request.getPhone());
                return Result.error("密码错误");
            }
            
            // 检查用户状态
            if (!user.getIsActive()) {
                log.warn("用户已被禁用: phone={}", request.getPhone());
                return Result.error("账号已被禁用");
            }
            
            if (!userRole.getIsActive()) {
                log.warn("用户角色已被禁用: phone={}", request.getPhone());
                return Result.error("账号权限已被禁用");
            }
            
            // 生成JWT令牌
            String token = jwtUtil.generateToken(user.getId(), user.getOpenid());
            
            // 构建返回数据
            Map<String, Object> data = new HashMap<>();
            data.put("token", token);
            data.put("user", user);
            data.put("role", userRole.getRoleType());
            data.put("roleName", userRole.getRoleName());
            
            log.info("用户登录成功: userId={}, phone={}, role={}", 
                    user.getId(), request.getPhone(), userRole.getRoleType());
            
            // 记录用户操作（仅记录普通用户）
            notificationService.recordUserAction(user, "LOGIN", 
                    String.format("用户通过手机号密码登录系统，角色: %s", userRole.getRoleName()));
            
            return Result.success("登录成功", data);
            
        } catch (Exception e) {
            log.error("登录失败: phone={}", request.getPhone(), e);
            return Result.error("登录失败: " + e.getMessage());
        }
    }
    

    
    /**
     * 获取当前用户信息
     */
    @GetMapping("/me")
    public Result<Map<String, Object>> getCurrentUser(@RequestHeader("Authorization") String authorization) {
        try {
            // 从token中解析用户ID
            Long userId = jwtUtil.getUserIdFromToken(authorization);
            
            // 获取用户信息
            User user = userService.getById(userId);
            if (user == null) {
                return Result.error("用户不存在");
            }
            
            // 获取用户角色信息
            UserRole userRole = userRoleService.getUserRole(userId);
            if (userRole == null) {
                return Result.error("用户角色不存在");
            }
            
            // 构建返回数据
            Map<String, Object> data = new HashMap<>();
            data.put("user", user);
            data.put("role", userRole.getRoleType());
            data.put("roleName", userRole.getRoleName());
            
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取用户信息失败", e);
            return Result.error("获取用户信息失败: " + e.getMessage());
        }
    }
    
    /**
     * 手机号登录请求DTO
     */
    public static class PhoneLoginRequest {
        @NotBlank(message = "手机号不能为空")
        @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
        private String phone;
        
        @NotBlank(message = "密码不能为空")
        private String password;
        
        // Getters and Setters
        public String getPhone() {
            return phone;
        }
        
        public void setPhone(String phone) {
            this.phone = phone;
        }
        
        public String getPassword() {
            return password;
        }
        
        public void setPassword(String password) {
            this.password = password;
        }
    }
}